﻿#region Copyright

// The contents of this file are subject to the Mozilla Public License
//  Version 1.1 (the "License"); you may not use this file except in compliance
//  with the License. You may obtain a copy of the License at
//  
//  http://www.mozilla.org/MPL/
//  
//  Software distributed under the License is distributed on an "AS IS"
//  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
//  License for the specific language governing rights and limitations under 
//  the License.
//  
//  The Initial Developer of the Original Code is Robert Smyth.
//  Portions created by Robert Smyth are Copyright (C) 2008.
//  
//  All Rights Reserved.

#endregion

using System.IO;
using System.Reflection;
using System.Windows;
using NUnitGrid.Framework.Logging;


namespace NUnitGrid.GridClient.Plugins.GridClient.NUnitTestsFinder
{
    public class TestsFinder : ITestsFinder
    {
        private readonly ILogger logger;

        public TestsFinder(ILogger logger)
        {
            this.logger = logger;
        }

        public string[] GetTests(string testAssemblyFullPath)
        {
            var newFixturesCount = 0;
            var testFixtues = new string[0];

            var nunitAssemblyPath = Path.Combine(Path.GetDirectoryName(testAssemblyFullPath), "nunit.framework.dll");
            var nunitFramework = GetAssembly(nunitAssemblyPath);
            if (nunitFramework != null)
            {
                var testFixtureAttribute = nunitFramework.GetType("NUnit.Framework.TestFixtureAttribute");
                if (testFixtureAttribute == null)
                {
                    logger.Error.Write("Unable to get test fixture attribute from NUnit framework dll.");
                }

                var assemblyFullPath = ClientSettings.Default.TestAssembly;
                if (File.Exists(assemblyFullPath))
                {
                    var testAssembly = Assembly.LoadFrom(assemblyFullPath);

                    var fixtureFinder = new FixtureFinder(testAssembly, testFixtureAttribute);
                    testFixtues = fixtureFinder.GetTestFixtures();
                }
                else
                {
                    logger.Info.Write("Error: Unable to find test assembly {0}.", assemblyFullPath);
                }

                logger.Info.Write("\nLoaded {0} fixtures.", testFixtues.Length);
                if (newFixturesCount > 0)
                {
                    logger.Warning.Write("Warning: Using default run time for {0} new fixtures.\n",
                                         newFixturesCount);
                }
            }
            else
            {
                var message =
                    string.Format(
                        "Unable to find '{0}'.\n\nCheck that the required NUnit assemblies have been loaded into the test assembly folder.",
                        nunitAssemblyPath);
                logger.Error.Write(message);
                MessageBox.Show(message, "Error");
            }

            return testFixtues;
        }

        private Assembly GetAssembly(string assemblyFullPath)
        {
            Assembly assembly = null;
            if (File.Exists(assemblyFullPath))
            {
                assembly = Assembly.LoadFrom(assemblyFullPath);
                if (assembly == null)
                {
                    logger.Warning.Write("Error: Unable to load '{0}'.", assemblyFullPath);
                }
            }
            return assembly;
        }
    }
}